﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Threading;
using BlackListDataSyn.CsMail;


namespace BlackListDataSyn
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":-----------开始执行调用API程序---------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------开始执行调用API程序----------");

                StartAPITask();

                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":------------执行调用API程序结束----------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------执行调用API程序结束----------");


                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":------------开始读大数据文件，插入临时表----------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------开始读大数据文件，插入临时表---------");

                StartDBTask();

                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":------------执行大数据插入数据库结束----------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------执行大数据插入数据库结束----------");

                BLL.BlackFileInfo.instance.SendMail("黑名单同步成功！");


                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":------------开始分发数据到各个数据库----------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------开始分发数据到各个数据库----------");

                StartDistributionTask();

                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":------------分发数据到各个数据库结束----------");
                System.Console.WriteLine(DateTime.Now.ToString() + ":------------分发数据到各个数据库结束----------");

            }
                
            catch (Exception ex)
            {
                LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + ":" + ex.ToString());
                BLL.BlackFileInfo.instance.SendMail("黑名单同步失败！");
            }
        }   

        public static string access_token = string.Empty;

        private static void StartAPITask()
        {
            string url = string.Empty;
            string result = string.Empty;
            string app_id = string.Empty;
            string app_secret = string.Empty;
            string ParkingNo = string.Empty;            

            #region appid& app_secrect,密钥请求
            app_id = ConfigurationManager.AppSettings["app_id"].ToString();
            app_secret = ConfigurationManager.AppSettings["app_secret"].ToString();
            url = ConfigurationManager.AppSettings["URL"].ToString();
            ParkingNo = ConfigurationManager.AppSettings["ParkingNo"].ToString();

            string App_url = string.Format("{0}/access_token", url);

            Dictionary<string, string> Param = new Dictionary<string, string>();
            Param.Add("app_id", app_id);
            Param.Add("app_secret", app_secret);
            Param.Add("grant_type", "client_credential");      

            //首次请求,得到access_token和expires_in
            result = HttpHelper.CreateHttpGetResponse(App_url, Param);
            ResponeseData response = null;

            if (result != null && result.Length > 0)
            {
                response = JsonHelper.ParseFormByJson<ResponeseData>(result);
            }
            #endregion

            //请求成功
            if (response.code == "0" && response.msg=="success")
            {
                #region 黑名单请求
                LogHelper.Instance.WriteFileLog(string.Format("用户app_id:{0},app_secret:{1}授权成功，返回access_token：{2}", app_id, app_secret,response.data.access_token));

                access_token = response.data.access_token;

                long TimeStamp = Utility.ConvertDateTimeToInt(DateTime.Now);

                string straccess_token = string.Format("AccessToken={0}", access_token);
                string strtimestamp = string.Format("TimeStamp={0}", TimeStamp);

                string SignStr = straccess_token + "&" + strtimestamp;
                string SignKey = app_secret;
                string SignEncryBefore = SignStr + SignKey;

                string SignEncryAfter = System.Web.Security.FormsAuthentication.
           HashPasswordForStoringInConfigFile(SignEncryBefore, "sha1").ToLower();

                string backlistUrl = string.Format("{0}/parking/blacklist",url);         

                RequstBlacklist requestblacklist = new RequstBlacklist();
                requestblacklist.AccessToken = access_token;
                requestblacklist.TimeStamp = TimeStamp;
                requestblacklist.Sign = SignEncryAfter;

                string strJson = JsonHelper.GetJSON<RequstBlacklist>(requestblacklist);

                #endregion

                try
                {
                    #region
                    LogHelper.Instance.WriteFileLog(string.Format("黑名单列表数据，access_token:{0},TimeStamp:{1},sign:{2}", access_token, TimeStamp, SignEncryAfter));

                    string BlackResult = HttpHelper.CreateHttpPostResponse(backlistUrl, access_token, strJson);

                    if (!string.IsNullOrEmpty(BlackResult))
                    {
                        //获取黑名单列表数据。
                        ResponeseBlackData BlackResponse = JsonHelper.ParseFormByJson<ResponeseBlackData>(BlackResult);

                        if (BlackResponse.code == "0" && BlackResponse.msg == "success")
                        {
                            #region
                            LogHelper.Instance.WriteFileLog(string.Format("获取黑名单列表数据成功,code={0},msg:{1}！",BlackResponse.code,BlackResponse.msg));

                            //查询当前的fileid,取最新的，判断id大小,需要优化

                            List<blackData> Blacklist = BlackResponse.data;

                            int FileId =0;
                            string strLinkaccess_token =string.Empty ;

                            int FileTempId=0;

                            for(int i=0;i<Blacklist.Count;i++)
                            {
                                //找到最新的fileid
                               FileId =Blacklist[i].Id;
                               if (FileId > FileTempId)
                               {
                                   FileTempId = FileId;
                               }
                            }

                            FileId = FileTempId;

                            #endregion

                            //申请黑名单下载链接URL

                            #region 申请黑名单下载链接URL
                            string LinkUrl = string.Format("{0}/parking/blacklist/load", url);

                            string strId = string.Format("Id={0}", FileId.ToString());

                            string strParkingNo = string.Format("ParkingNo={0}", ParkingNo);

                            string SignLinkStr = straccess_token + "&" + strId + "&" + strParkingNo + "&" + strtimestamp;

                            LogHelper.Instance.WriteFileLog(string.Format("黑名单请求的string:{0}", SignLinkStr));

                            string SignLinkEncryBefore = SignLinkStr + SignKey;

                            LogHelper.Instance.WriteFileLog(string.Format("黑名单请求的string+key:{0}", SignLinkEncryBefore));

                            string SignLinkEncryAfter = System.Web.Security.FormsAuthentication.
        HashPasswordForStoringInConfigFile(SignLinkEncryBefore, "sha1").ToLower();

                            LogHelper.Instance.WriteFileLog(string.Format("黑名单请求的SHA1加密后的结果:{0}", SignLinkEncryAfter));

                            RequestLinkBlacklist requsetlinkblacklist = new RequestLinkBlacklist();
                            requsetlinkblacklist.AccessToken = access_token;
                            requsetlinkblacklist.Id = FileId;
                            requsetlinkblacklist.ParkingNo = ParkingNo;
                            requsetlinkblacklist.TimeStamp = TimeStamp;
                            requsetlinkblacklist.Sign = SignLinkEncryAfter;

                            #endregion

                            #region
                            try
                            {
                                string strLinkJosn = JsonHelper.GetJSON<RequestLinkBlacklist>(requsetlinkblacklist);

                                string BlackLinkResult = HttpHelper.CreateHttpPostResponse(LinkUrl, access_token, strLinkJosn);

                                if (!string.IsNullOrEmpty(BlackLinkResult))
                                {
                                    //获取黑名单列表数据。
                                    ResponseLink responselink = JsonHelper.ParseFormByJson<ResponseLink>(BlackLinkResult);
                                    string DownloadUrl = responselink.data.Source;
                                    string Filename = responselink.data.Filename;
                                    
                                    LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + string.Format(":黑名单文件的地址为{0},开始下载", DownloadUrl));                              

                                    //下载黑名单
                                   bool iDownload = HttpDownload.Instance.Download(DownloadUrl);
                                   if (iDownload)
                                   {
                                       LogHelper.Instance.WriteFileLog(DateTime.Now.ToString() + string.Format(":黑名单文件的地址为{0},下载完成！", DownloadUrl));  
                                   }
                                }
                            }
                            catch (Exception ex)
                            {
                                LogHelper.Instance.WriteFileLog(ex.ToString() + "---" + DateTime.Now.Ticks.ToString("x"));
                            }

                            #endregion
                        }
                    }
                    #endregion
                }
                catch (Exception ex)
                {                   
                    LogHelper.Instance.WriteFileLog(ex.ToString()); 
                    throw ex;
                }
            }
        }

        private static void StartDBTask()
        {
            string Path = BaseIni.GetFilePath();

            List<BlackListDataSyn.DAL.ETCBlackFileInfo> etcblackfileinfo = BLL.ETCBlackFileInfo.Instance.Read(Path);

            Console.WriteLine(DateTime.Now.ToString() + ":文件读取完成！");   

           //清理历史数据
           BLL.ETCBlackFileInfo.ClearTable();

           //插入到临时表
           BLL.ETCBlackFileInfo.Instance.SqlBulkCopyByDatatable("ETCBlackFileInfo_Temp", etcblackfileinfo);

           Console.WriteLine(DateTime.Now.ToString() + ":插入到临时表完成！");

           //同步新增数据到主表
           BLL.ETCBlackFileInfo.Instance.ExecuteSynData();

           Console.WriteLine(DateTime.Now.ToString() + ":同步新增数据到主表完成！");

           //如果临时表数据已删除，主表也相应删除
           BLL.ETCBlackFileInfo.Instance.ExecuteDiffData();

           Console.WriteLine(DateTime.Now.ToString() + ":如果临时表数据已删除，主表也相应删除完成！");

        }

        private static void StartDistributionTask()
        {
            List<string> ltConnectSet = BLL.ETCAppconfig.instance.DsConnectSet();
            if (ltConnectSet.Count > 0)
            {
                foreach (string str in ltConnectSet)
                {
                    //新开线程同步一个服务器
                    Thread Connect_invThread = new Thread(new ParameterizedThreadStart(DistributionDB));
                    Connect_invThread.IsBackground = true;
                    Connect_invThread.Start(str);
                }
            }
 
        }

        public static void DistributionDB(object connection)
        {
            try
            {
                string strConnection = connection.ToString();

                BLL.BlackFileInfo.instance.ExecuteSynData(strConnection);

                BLL.BlackFileInfo.instance.ExecuteDiffData(strConnection);
            }
            catch (Exception ex)
            {
                LogHelper.Instance.WriteFileLog(ex.ToString());
            }
        } 
    }
}
